package cn.tedu.shoot;
import java.util.Timer;
import java.util.TimerTask;//定时任务；

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.Graphics;
import java.util.Random;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;//
import java.awt.event.MouseEvent;//

public class World extends JPanel{
	public static final int WIDTH = 512;
	public static final int HEIGHT = 768;//常量

	public static final int START = 0;
	public static final int RUNNING = 1;
	public static final int PAUSE = 2;
	public static final int GAME_OVER = 3;
	public int state = START;

	private BossBullet[]bossBullets= {};
	private Boss boss;
	public int score = 0;
	private Sky sky = new Sky();
	private Hero hero = new Hero();
	private FlyingObject[] enemies = {};  //成员变量声明时先赋值，避免空指针异常。
	private Bullet[] bullets = {}; 
	private Laser laser;

	public FlyingObject nextOne() {//随机产生敌机
		Random rand = new Random();
		int type = rand.nextInt(20);	
		if(type<4) {
			return new Bee();
		}else if(type<13){
			return new Airplane();
		}else {
			return new BigAirplane();
		}
	}
	int bossIndex=0;
	public Boss bossEnterAction() {//boss进场
		bossIndex++;
		if(bossIndex%4000==0) {
			return boss=new Boss();
		}
		return null;

	}
	public void bossAction() {//boss子弹入场
		if(shootIndex%400==0) {
			BossBullet[] bs=boss.shoot();
			bossBullets=Arrays.copyOf(bossBullets, bossBullets.length+bs.length);	
			System.arraycopy(bs,0,bossBullets,bossBullets.length-bs.length,bs.length );
		}
	}
	//interface implement


	/** 控制敌人入场*/
	int enterIndex = 0;
	public void enterAction() {
		enterIndex++;
		if(enterIndex%40==0) {
			FlyingObject obj = nextOne();
			enemies = Arrays.copyOf(enemies, enemies.length+1);
			enemies[enemies.length-1] = obj;
		}
	}

	int shootIndex = 0;
	int timeIndex = 0;
	public void shootAction() {//英雄机子弹进场
		shootIndex++;
		if(shootIndex%20==0) {
			Bullet[] bs = hero.shoot();
			bullets = Arrays.copyOf(bullets, bullets.length+bs.length);//数组的追加；	
			System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length);

		}
	}

	//防止遍历对象时发生空指针异常。
	public void stepAction() {
		sky.step();
		if(laser!=null) {
			laser.step();
		}
		for(int i =0;i<enemies.length;i++) {					
			enemies[i].step();
		}
		for(int i=0;i<bullets.length;i++) {
			bullets[i].step();
		}
		for(int i=0;i<bossBullets.length;i++) {
			bossBullets[i].step();
		}
	}
	public void outOfBoundsAction() {//越界
		FlyingObject[] enemyLives = new FlyingObject[enemies.length];
		int index = 0;
		for(int i=0;i<enemies.length;i++) {
			FlyingObject f = enemies[i];
			if(!f.outOfBouds()&&!f.isRemove()) {//如果敌人或子弹不越界，则将其添加到不越界数组
				enemyLives[index] = enemies[i];
				index++;
			}	
		}	
		enemies = Arrays.copyOf(enemyLives, index);//把不越界数组复制到enemies数组中
		index = 0;
		Bullet[] bulletLives = new Bullet[bullets.length];
		for(int i=0;i<bullets.length;i++) {
			Bullet b = bullets[i];
			if(!b.outOfBouds()&&!b.isRemove()) {
				bulletLives[index] = bullets[i];
				index++;
			}	
		}
		bullets=Arrays.copyOf(bulletLives, index);
		index=0;
		BossBullet[]bossBulletLives=new BossBullet[bossBullets.length];
		for(int i=0;i<bossBulletLives.length;i++) {
			BossBullet b=bossBullets[i];
			if(!b.outOfBouds()&&!b.isRemove()) {
				bossBulletLives[index]=b;
				index++;
			}
		}
		bossBullets=Arrays.copyOf(bossBulletLives, index);
	}
	public void bulletBangAction() {//英雄机子弹与boss和敌机碰撞

		for(int i=0;i<bullets.length;i++) {
			Bullet b = bullets[i];
			if(boss!=null&&!boss.isRemove()) {
				if(boss.isLife()&&b.isLife()&&boss.hit(b)) {
					b.goDead();
					boss.subtractLife();
					System.out.println(boss.getLife());
				}
			}
			for(int j=0;j<enemies.length;j++) {
				FlyingObject f = enemies[j];
				if(f.isLife() && b.isLife() && f.hit(b)) {
					b.goDead();
					f.goDead();
					if(f instanceof Enemy) {
						Enemy e =(Enemy)f;
						score+=e.getScore();
					}
					if(f instanceof Award) {
						Award a = (Award)f;
						int type = a.getAwardType();

						switch(type) {
						case Award.DOUBLE_FIRE:
							hero.addDoubleFire();
							break;
						case Award.ANGER_SLOT:
							hero.addAngerSlot();
							break;
						}
					}	
				}

			}
		}
	}
	public void bossGameOverAction() {//boss死亡
		if(boss.getLife()<=0) {
			boss.goDead();
			if(boss instanceof Enemy) {
				Enemy e=(Enemy)boss;
				score+=e.getScore();
			}
		}
	}
	public void laserBangAction() {//英雄机大招与boss和敌机碰撞
		if(laser!=null&&boss!=null&&!boss.isRemove()) {
			if(boss.isLife()&&boss.hit(laser)) {
				boss.laserSubtractLife();
			}
			for(int i=0;i<bossBullets.length;i++) {
				BossBullet b=bossBullets[i];
				if(boss!=null&&!boss.isRemove()) {
					if(b.isLife()&&b.hit(laser)) {
						b.goDead();
					}
				}
			}
			
		}		
		for(FlyingObject f: enemies) {
			if(laser!=null) {				
				if(f.isLife() && f.hit(laser)) {
					f.goDead();
					if(f instanceof Enemy) {
						Enemy e =(Enemy)f;
						score+=e.getScore();
					}
					if(f instanceof Award) {
						Award a = (Award)f;
						int type = a.getAwardType();
						switch(type) {
						case Award.DOUBLE_FIRE:
							hero.addDoubleFire();
							break;
						case Award.ANGER_SLOT:
							hero.addAngerSlot();
							break;	
						}
					}
				}
			}
		}
	}

	public void heroBangAction(){//英雄机与敌人碰撞
		for(int i=0;i<bossBullets.length;i++) {
			BossBullet b=bossBullets[i];
			if(boss!=null&&!boss.isRemove()) {
				if(b.isLife()&&hero.isLife()&&b.hit(hero)) {
					b.goDead();
					hero.substractLife();
					hero.clearDoubleFire();
					System.out.println(hero.getLife());
				}
			}

		}
		if(boss!=null&&!boss.isRemove()) {
			if(boss.isLife()&&hero.isLife()&&hero.hit(boss)) {
				hero.substractLife();
				hero.clearDoubleFire();
				boss.subtractLife();
			}
		}
		for(int i =0;i<enemies.length;i++) {
			FlyingObject f = enemies[i];
			if(hero.isLife()&&f.isLife()&&f.hit(hero)) {
				f.goDead();
				hero.substractLife();
				hero.clearDoubleFire();

			}
		}

	}

	public void checkGameOverAction() {//结束游戏
		if(hero.getLife() <= 0) {
			state = GAME_OVER;
		}
	}
	/** 计时 */
	public void action() { //启动程序的执行
		MouseAdapter l = new MouseAdapter() {
			public void mouseMoved(MouseEvent e) {				
				if(state == RUNNING) {
					int x = e.getX();
					int y = e.getY();
					hero.moveTo(x, y);
					/*
					 * 激光随鼠标动
					 */
				}		
			}
			public void mouseClicked(MouseEvent e) {
				switch(state) {
				case START:
					hero = new Hero();
					state = RUNNING;
					break;
				case GAME_OVER:
					score = 0;
					boss=null;
					bossBullets=new BossBullet[0];
					sky = new Sky();
					hero = new Hero();
					enemies = new FlyingObject[0];
					bullets = new Bullet[0];
					laser = null;
					state = START;
					break;
				}	
			}
			public void mouseExited(MouseEvent e) {
				if(state==RUNNING) {
					state = PAUSE; 
				}   
			}
			public void mouseEntered(MouseEvent e) {
				if(state==PAUSE) {
					state = RUNNING;
				}	
			} 
		};
		KeyListener k = new KeyAdapter() {
			public void keyReleased(KeyEvent v) {
				if(v.getKeyCode()==KeyEvent.VK_ESCAPE) {
					if((state==RUNNING)) {
						state = PAUSE;
					}else if(state ==PAUSE) {
						state=RUNNING;
					}
				}
			}
			/*
			 * f1控制激光射击（满足发射激光的条件的话）
			 * @see java.awt.event.KeyAdapter#keyPressed(java.awt.event.KeyEvent)
			 */

			public void keyPressed(KeyEvent v) {
				if(v.getKeyCode()==KeyEvent.VK_F1) {
					if(hero.getAngerSlot()==3) {
						laser = new Laser();
						hero.clearAngerSlot();
					}
				}
			}
		};
		this.setFocusable(true);
		this.addKeyListener(k);
		this.addMouseListener(l);
		this.addMouseMotionListener(l);
		Timer timer = new Timer();
		int intervel = 10;
		timer.schedule(new TimerTask() {	
			public void run() {
				if(state == RUNNING) {
					if(boss==null||boss.isRemove()) {
						enterAction();
					}
					shootAction();
					stepAction();
					outOfBoundsAction();
					bulletBangAction();
					laserBangAction();
					heroBangAction();
					bossEnterAction();
					if(boss!=null&&!boss.isRemove()) {
						bossAction();
						bossGameOverAction();

					}
					checkGameOverAction();
				}
				repaint();
			}
		}, intervel,intervel);	
	}	

	public void paint(Graphics g) {
		sky.paintObject(g);
		hero.paintObject(g);
		if(boss!=null&&!boss.isRemove()) {
			boss.paintObject(g);
			for(int i=0;i<bossBullets.length;i++) {
				bossBullets[i].paintObject(g);
			}
		}
		for(int i=0;i<enemies.length;i++) {
			enemies[i].paintObject(g);
		}
		for(int i=0;i<bullets.length;i++) {
			bullets[i].paintObject(g);
		}
		if(laser!=null) {
			laser.paintObject(g);
		}
		g.drawString("SCORE:"+score,10,20);
		g.drawString("LIFE:"+hero.getLife(),10,30);
		g.drawString("DoubleFire:"+hero.getDoubleFire(),10,40);
		g.drawString("AngerSlot:"+hero.getAngerSlot(),10,50);
		switch(hero.getAngerSlot()) {
		case 0:
			g.drawImage(Images.angerslots[0],10,60,null);
			break;
		case 1:
			g.drawImage(Images.angerslots[1],10,60,null);
			break;
		case 2:
			g.drawImage(Images.angerslots[2],10,60,null);
			break;
		case 3:
			g.drawImage(Images.angerslots[3],10,60,null);
			break;
		}
		switch(state) {		
		case START:
			g.drawImage(Images.start,120,246,null);
			break;
		case PAUSE:
			g.drawImage(Images.pause,102,246,null);
			break;
		case GAME_OVER:
			g.drawImage(Images.gameover,120,246,null);
			break;
		}

	}
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		World game = new World(); 
		frame.add(game); 		
		frame.setSize(WIDTH,HEIGHT);
		frame.setAlwaysOnTop(true); 
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		frame.setIconImage(new ImageIcon("images/icon.jpg").getImage());
		frame.setLocationRelativeTo(null); 
		frame.setVisible(true); //1)设置窗口可见2）尽快调用paint方法--jpanel的paint
		game.action(); 
	}
}
